package com.weilele.leisure.video_factory.utils

import android.content.ContentUris
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.os.Parcelable
import android.provider.MediaStore
import androidx.core.database.getDoubleOrNull
import androidx.core.database.getIntOrNull
import androidx.core.database.getLongOrNull
import androidx.core.database.getStringOrNull
import com.weilele.mvvm.adapter.ignoreError
import com.weilele.mvvm.app
import kotlinx.parcelize.Parcelize

private val sLocalVideoColumns = arrayOf(
    MediaStore.Video.Media._ID,  // 视频id
    MediaStore.Video.Media.DATA,  // 视频路径
    MediaStore.Video.Media.SIZE,  // 视频字节大小
    MediaStore.Video.Media.DISPLAY_NAME,  // 视频名称 xxx.mp4
    MediaStore.Video.Media.TITLE,  // 视频标题
    MediaStore.Video.Media.DATE_ADDED,  // 视频添加到MediaProvider的时间
    MediaStore.Video.Media.DATE_MODIFIED,  // 上次修改时间，该列用于内部MediaScanner扫描，外部不要修改
    MediaStore.Video.Media.MIME_TYPE,  // 视频类型 video/mp4
    MediaStore.Video.Media.DURATION,  // 视频时长
    MediaStore.Video.Media.ARTIST,  // 艺人名称
    MediaStore.Video.Media.ALBUM,  // 艺人专辑名称
    MediaStore.Video.Media.RESOLUTION,  // 视频分辨率 X x Y格式
    MediaStore.Video.Media.DESCRIPTION,  // 视频描述
    MediaStore.Video.Media.IS_PRIVATE,
    MediaStore.Video.Media.TAGS,
    MediaStore.Video.Media.CATEGORY,  // YouTube类别
    MediaStore.Video.Media.LANGUAGE,  // 视频使用语言
    MediaStore.Video.Media.LATITUDE,  // 拍下该视频时的纬度
    MediaStore.Video.Media.LONGITUDE,  // 拍下该视频时的经度
    MediaStore.Video.Media.DATE_TAKEN,
    MediaStore.Video.Media.MINI_THUMB_MAGIC,
    MediaStore.Video.Media.BUCKET_ID,
    MediaStore.Video.Media.BUCKET_DISPLAY_NAME,
    MediaStore.Video.Media.BOOKMARK, // 上次视频播放的位置
    MediaStore.Video.Media.WIDTH, // 上次视频播放的位置
    MediaStore.Video.Media.HEIGHT, // 上次视频播放的位置
)

@Parcelize
data class MediaVideoInfo(
    var id: Long,
    var uri: Uri,
    var coverUri: String? = null,
    var data: String? = null,
    var size: Long? = null,
    var displayName: String? = null,
    var title: String? = null,
    var dateAdded: Long? = null,
    var dateModified: Long? = null,
    var mimeType: String? = null,
    var duration: Long? = null,
    var artist: String? = null,
    var album: String? = null,
    var resolution: String? = null,
    var description: String? = null,
    var isPrivate: Int? = null,
    var tags: String? = null,
    var category: String? = null,
    var latitude: Double? = null,
    var longitude: Double? = null,
    var dateTaken: Int? = null,
    var miniThumbMagic: Int? = null,
    var bucketId: String? = null,
    var bucketDisplayName: String? = null,
    var bookmark: Long? = null,
    var width: Int? = null,
    var height: Int? = null,
) : Parcelable {
    fun toJsonString(): String {
        return "VideoInfo{" +
                "id=" + id +
                ", data='" + data + '\'' +
                ", size=" + size +
                ", displayName='" + displayName + '\'' +
                ", title='" + title + '\'' +
                ", dateAdded=" + dateAdded +
                ", dateModified=" + dateModified +
                ", mimeType='" + mimeType + '\'' +
                ", duration=" + duration +
                ", artist='" + artist + '\'' +
                ", album='" + album + '\'' +
                ", resolution='" + resolution + '\'' +
                ", description='" + description + '\'' +
                ", isPrivate=" + isPrivate +
                ", tags='" + tags + '\'' +
                ", category='" + category + '\'' +
                ", latitude=" + latitude +
                ", longitude=" + longitude +
                ", dateTaken=" + dateTaken +
                ", miniThumbMagic=" + miniThumbMagic +
                ", bucketId='" + bucketId + '\'' +
                ", bucketDisplayName='" + bucketDisplayName + '\'' +
                ", bookmark=" + bookmark +
                ", width=" + width +
                ", height=" + height +
                '}'
    }
}

fun getLocalVideoInfo(): MutableList<MediaVideoInfo> {
    val mVideoInfos = mutableListOf<MediaVideoInfo>()
    val queryUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
    val cursor: Cursor? = app.contentResolver.query(
        queryUri, sLocalVideoColumns,
        null, null, null
    )
    if (cursor != null && cursor.moveToFirst()) {
        do {
            ignoreError {
                //region 过滤掉小于1k的音频
                val size = cursor.getLongOrNull(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE))
                if (size == null || size < 1024) {
                    return@ignoreError
                }
                val id = cursor.getLongOrNull(cursor.getColumnIndex(MediaStore.Video.Media._ID))
                    ?: return@ignoreError

                //endregion
                val videoInfo = MediaVideoInfo(id, ContentUris.withAppendedId(queryUri, id))
                val data =
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !Environment.isExternalStorageLegacy()) {
                        cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Video.Media.RELATIVE_PATH))
                            ?: cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Video.Media.DATA))
                    } else {
                        cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Video.Media.DATA))
                    }
                val displayName =
                    cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Video.Media.DISPLAY_NAME))
                val title =
                    cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Video.Media.TITLE))
                val dateAdded =
                    cursor.getLongOrNull(cursor.getColumnIndex(MediaStore.Video.Media.DATE_ADDED))
                val dateModified =
                    cursor.getLongOrNull(cursor.getColumnIndex(MediaStore.Video.Media.DATE_MODIFIED))
                val mimeType =
                    cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Video.Media.MIME_TYPE))
                val duration =
                    cursor.getLongOrNull(cursor.getColumnIndex(MediaStore.Video.Media.DURATION))
                val artist =
                    cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Video.Media.ARTIST))
                val album =
                    cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Video.Media.ALBUM))
                val resolution =
                    cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Video.Media.RESOLUTION))
                val description =
                    cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Video.Media.DESCRIPTION))
                val isPrivate =
                    cursor.getIntOrNull(cursor.getColumnIndex(MediaStore.Video.Media.IS_PRIVATE))
                val tags =
                    cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Video.Media.TAGS))
                val category =
                    cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Video.Media.CATEGORY))
                val latitude =
                    cursor.getDoubleOrNull(cursor.getColumnIndex(MediaStore.Video.Media.LATITUDE))
                val longitude =
                    cursor.getDouble(cursor.getColumnIndex(MediaStore.Video.Media.LONGITUDE))
                val dateTaken =
                    cursor.getIntOrNull(cursor.getColumnIndex(MediaStore.Video.Media.DATE_TAKEN))
                val miniThumbMagic =
                    cursor.getIntOrNull(cursor.getColumnIndex(MediaStore.Video.Media.MINI_THUMB_MAGIC))
                val bucketId =
                    cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_ID))
                val bucketDisplayName =
                    cursor.getStringOrNull(cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_DISPLAY_NAME))
                val bookmark =
                    cursor.getLongOrNull(cursor.getColumnIndex(MediaStore.Video.Media.BOOKMARK))
                val width =
                    cursor.getIntOrNull(cursor.getColumnIndex(MediaStore.Video.Media.WIDTH))
                val height =
                    cursor.getIntOrNull(cursor.getColumnIndex(MediaStore.Video.Media.HEIGHT))
                videoInfo.coverUri = videoInfo.uri.toString()
                videoInfo.id = id
                videoInfo.data = data
                videoInfo.size = size
                videoInfo.displayName = displayName
                videoInfo.title = title
                videoInfo.dateAdded = dateAdded
                videoInfo.dateModified = dateModified
                videoInfo.mimeType = mimeType
                videoInfo.duration = duration
                videoInfo.artist = artist
                videoInfo.album = album
                videoInfo.resolution = resolution
                videoInfo.description = description
                videoInfo.isPrivate = isPrivate
                videoInfo.tags = tags
                videoInfo.category = category
                videoInfo.latitude = latitude
                videoInfo.longitude = longitude
                videoInfo.dateTaken = dateTaken
                videoInfo.miniThumbMagic = miniThumbMagic
                videoInfo.bucketId = bucketId
                videoInfo.bucketDisplayName = bucketDisplayName
                videoInfo.bookmark = bookmark
                videoInfo.width = width
                videoInfo.height = height
                mVideoInfos.add(videoInfo)
            }
        } while (cursor.moveToNext())
        cursor.close()
    }
    return mVideoInfos
}